#include <stdio.h>
#include <omp.h>
#include <time.h>
#include <sys/time.h>
#include <unistd.h>
#include "user_buzz.h"
#include <sys/types.h>
#include <sys/syscall.h>

#define THREADCOUNT 100
#define THREADPOOL 5   

#define TIMEOUT 10  // in us
#define ACTIVITY 5 // in us
bzz_t GTLOCK;

void my_usleep() {
    struct timespec t1, t2;
    clock_gettime(CLOCK_REALTIME, &t1);
    do {
        clock_gettime(CLOCK_REALTIME, &t2);
    } while((t2.tv_nsec - t1.tv_nsec) < ACTIVITY && t2.tv_nsec > t1.tv_nsec);
}

void thread(){
    struct timespec t5,t6;
    double elapsedTime, ns, total;
    int ID = omp_get_thread_num();
    
    
    if(ID % 2 > 0)
        bzz_color(BZZ_GOLD, GTLOCK);
    else bzz_color(BZZ_BLACK, GTLOCK);
    
    clock_gettime(CLOCK_REALTIME, &t5);
    bzz_lock(GTLOCK);
    clock_gettime(CLOCK_REALTIME, &t6);
    
    usleep(ACTIVITY);
    
    bzz_release(GTLOCK);
    
#pragma omp barrier    
    elapsedTime = (t6.tv_sec - t5.tv_sec) * 1000000;      // sec to usec
    ns = (t6.tv_nsec - t5.tv_nsec)/1000.0;      // nsec to usec
    total = elapsedTime + ns;
    if(ID % 2 > 0){   
        printf("GOLD: %.2fus \n", total);
    }
    else{
        printf("BLACK: %.2fus \n", total);
    }
}


int main(){
    
    omp_set_num_threads(THREADCOUNT);
    init_bzz(&GTLOCK,THREADPOOL,TIMEOUT); 
    
    
    #pragma omp parallel
    {
        
        thread();
        
    }
    
    bzz_kill(GTLOCK);
    
}


